package ca.nfb.media.nfbPlayer
{
	
	import ca.nfb.media.nfbPlayer.net.Remoter;
	import ca.nfb.media.nfbPlayer.views.BookmarksView;
	import ca.turbulent.media.Pyro;
	
	import flash.display.Loader;
	import flash.external.ExternalInterface;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.IOErrorEvent;
	import flash.events.ProgressEvent;
	import flash.events.SecurityErrorEvent;
	import flash.external.ExternalInterface;
	import flash.net.URLLoader;
	import flash.net.URLRequest;
	import flash.system.Capabilities;
	import flash.xml.*;

	public class ComModule extends EventDispatcher
	{
		public static const COMMENTS_SENT_EVENT				:String = "commentsSentEvent";
		public static const EMBED_RECEIVED_EVENT			:String = "embedReceivedEvent";
		public static const ERROR_EVENT						:String = "errorEvent";
		public static const FILE_URL_RECEIVED_EVENT			:String = "fileURLReceivedEvent";
		public static const MESSAGES_RECEIVED_EVENT			:String = "messagesReceived";
		public static const PLAYLIST_RECEIVED_EVENT			:String = "playlistReceivedEvent";
		public static const VIDEO_VOTES_RECEIVED_EVENT		:String = "videoVotesReceivedEvent";
		public static const VIDEO_VOTE_SENT_EVENT			:String = "videoVoteSentEvent";
		public static const VIDEO_LINK_RECEIVED_EVENT		:String = "videoLinkReceivedEvent";
		public static const EMAIL_SENT_SUCCESS_EVENT		:String = "emailSentSuccessEvent";
		public static const BOOKMARKS_RECEIVED_EVENT		:String = "bookmarksReceivedEvent";
		
		private static var __instance						:ComModule;
		private static var __lang							:String = "FR";
		
		private var xmlLoader								:URLLoader;
		private var bookmarksXML							:XML;
		
		public var defaultEmbedURLs							:Object = {prefix:'<embed src="http://YOURPATHTOTHEPLAYER.swf" width="516" ' + 
																		'height="337" allowfullscreen="true" allowscriptaccess="always" autostart="false" ' + 
																		'autoplay="false"', suffix:'&width=516&height=337&image=http://YOURPATHTOTHEIMAGE.jpg' + 
																		'&autostart=false&autoplay=false&streamNotFoundDelay=15&lang=en&embeddedMode=true">' + 
																		'</embed>/>'};
				
		public var bookmarksReceived						:Boolean = false;
		public var latestBookmarks							:Array = new Array();
		public var latestEmbed								:String = "";
		public var latestErrorMessage						:String = "";
		public var latestMessages							:Object = new Object();
		public var latestFileURL							:String = "";
		public var latestPackage							:Object = new Object();
		public var currentSpeedURLs							:Object = new Object();
		public var latestMovieHasDV							:Boolean = false;
		public var latestMovieHasCC							:Boolean = false;
		public var latestMovieHasCCDV						:Boolean = false;
		public var latestMovieHasExtremeSpeed				:Boolean = false;
		public var latestMovieHasNormalSpeed				:Boolean = false;
		public var latestMovieHasLowSpeed					:Boolean = false;
		public var latestDirectURL							:String = "";
		public var latestFileID								:String = "";																	
		public var latestMovieRating						:String = "";
		public var latestMovieMessages						:String = "";
		public var latestMovieDirectBuyURL					:String = "";
		public var latestFinalPlaylist						:Array = new Array();
		public var latestFinalPlaylistTitle					:String = "";
		public var latestFinalPlaylistDescription			:String = "";
		public var latestVotes								:String = "";
		public var latestMoviePackage						:Object = new Object();
		public var latestMovieDetails						:Object = new Object();
		public var latestSharingSites						:Object = new Object();						
		
		public var packageFromURL							:Boolean = false;						
		
		public var currentEmbed								:String = "";
		public var currentImage								:String = "";
		public var currentURL								:String = "";
		public var currentMovieInfos						:Object = {title:"", description:""};
		
		private var _core		 							:NFBPlayer;
		
		
		public static function getInstance():ComModule
		{
			if(!__instance)
				__instance = new ComModule();
				
			return __instance;
		}
		
		
		public static function getLang():String { return __lang; }
		public static function setLang(lang:String) { __lang = lang; }
		
		public function registerCore(pc:NFBPlayer):void { _core = pc; }
		
		public function getFlashVersion():Object
		{
			var version:String = Capabilities.version;
			var versionArray:Array = version.split(",");
			var versionObject:Object = {major:versionArray[0], minor:versionArray[1], build:versionArray[2], internalBuild:versionArray[3]};
			return versionObject;
		}
		
		
		
		public function output(msg:String):void
		{
			ExternalInterface.call("function(){alert('"+msg+"');}");
		}
		
		public function get core():NFBPlayer { return _core; } 
		
		
		/**
		 * 
		 * @param methodCalled
		 * 
		 */		
		
		private function dispatchGatewayCommError(methodCalled:String):void
		{
			latestErrorMessage = "Error in gateway communication :: "+methodCalled+" returned Fault";
			dispatchEvent(new Event(ComModule.ERROR_EVENT, false, false));
		}
	
		public function getBookmarks():void
		{
			if (core.bookmarksURL != "")
			{
				xmlLoader = new URLLoader();
				xmlLoader.addEventListener(ProgressEvent.PROGRESS, bookmarksProgress, false, 0, true);
				xmlLoader.addEventListener(Event.COMPLETE, bookmarksLoaded, false, 0, true);
				xmlLoader.addEventListener(IOErrorEvent.IO_ERROR, bookmarksError, false, 0, true);;
				xmlLoader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, bookmarksError, false, 0, true);
				
				xmlLoader.load(new URLRequest(core.bookmarksURL));
			}	
		}
		
		
		private function bookmarksProgress(evt:ProgressEvent):void
		{
			
		}
		
		private function bookmarksLoaded(evt:Event):void
		{
			var bookmarkXML:XML = new XML(xmlLoader.data);
			var bookmarksList:XMLList = bookmarkXML.bookmark;
			var bookmarksArr:Array = new Array();
			for each (var bkmk:XML in bookmarksList)
				bookmarksArr.push({time:parseBookmarkTime(bkmk.@time), en:bkmk.description_en.toString(), fr:bkmk.description_fr.toString() });
			
			latestBookmarks = bookmarksArr;
			bookmarksReceived = true;
			dispatchEvent(new Event(ComModule.BOOKMARKS_RECEIVED_EVENT));
		}
		
		private function parseBookmarkTime(timeCode:String):String
		{
			var timeArray:Array = timeCode.split(":");
			var lastTime:String = timeArray.pop();
			var returnedTime:String = "";
			for (var i:Number=0; i<timeArray.length; ++i)
			{
				returnedTime += String(timeArray[i]);
			
				if (i<timeArray.length-1)
					returnedTime += ":";
			}
			
			return returnedTime;
		}
		
		private function bookmarksError(evt:*=null):void
		{
			dispatchGatewayCommError("getBookmarks failed");
		}
	
		
		public function setStats(stat:String):void
		{
			// Send your stats somewhere from here
		}
				
		public function setURLs():void
		{
			if (latestPackage['low'] != null && latestPackage['low']['url'] && String(latestPackage['low']['url']).length > 0)
				this.latestMovieHasLowSpeed = true;
			else
				this.latestMovieHasLowSpeed = false;
				
			if (latestPackage['low'] != null && latestPackage['low']['cc_url'] && String(latestPackage['low']['cc_url']).length > 0)
				this.latestMovieHasLowSpeed = true;
				
			if (latestPackage['low'] != null && latestPackage['low']['dv_url'] && String(latestPackage['low']['dv_url']).length > 0)
				this.latestMovieHasLowSpeed = true;
			
			if (latestPackage['low'] != null && latestPackage['low']['cc_dv_url'] && String(latestPackage['low']['cc_dv_url']).length > 0)
				this.latestMovieHasLowSpeed = true;
					
			if (latestPackage['normal'] != null && latestPackage['normal']['url'] && String(latestPackage['normal']['url']).length > 0)
				this.latestMovieHasNormalSpeed = true;
			else
				this.latestMovieHasNormalSpeed = false;
				
			if (latestPackage['normal'] != null && latestPackage['normal']['cc_url'] && String(latestPackage['normal']['cc_url']).length > 0)
				this.latestMovieHasNormalSpeed = true;
			
			
			if (latestPackage['normal'] != null && latestPackage['normal']['dv_url'] && String(latestPackage['normal']['dv_url']).length > 0)
				this.latestMovieHasNormalSpeed = true;
						
			if (latestPackage['normal'] != null && latestPackage['normal']['cc_dv_url'] && String(latestPackage['normal']['cc_dv_url']).length > 0)
				this.latestMovieHasNormalSpeed = true;
					
			if (latestPackage['extreme'] != null && latestPackage['extreme']['url'] && String(latestPackage['extreme']['url']).length > 0)
				this.latestMovieHasExtremeSpeed = true;		
			else
				this.latestMovieHasExtremeSpeed = false;
				
			if (latestPackage['extreme'] != null && latestPackage['extreme']['cc_url'] && String(latestPackage['extreme']['cc_url']).length > 0)
				this.latestMovieHasExtremeSpeed = true;		
			
			if (latestPackage['extreme'] != null && latestPackage['extreme']['dv_url'] && String(latestPackage['extreme']['dv_url']).length > 0)
				this.latestMovieHasExtremeSpeed = true;		
				
			if (latestPackage['extreme'] != null && latestPackage['extreme']['cc_dv_url'] && String(latestPackage['extreme']['cc_dv_url']).length > 0)
				this.latestMovieHasExtremeSpeed = true;		
				 
				 
			if (!latestMovieHasLowSpeed && !latestMovieHasNormalSpeed && !latestMovieHasExtremeSpeed)
			{
				core.setCurrentState(NFBPlayer.FILE_NOT_FOUND_STATE);
				return;
			}			 
				 
			switch(core.player.streamQuality)
			{
				case Pyro.CONNECTION_SPEED_LOW:
				if (this.latestMovieHasLowSpeed)
				{	
					currentSpeedURLs = latestPackage['low'];
				}
				else
				{
					if (this.latestMovieHasNormalSpeed)
					{
						core.player.setStreamQuality(Pyro.CONNECTION_SPEED_MEDIUM);
						currentSpeedURLs = latestPackage['normal'];
					}
					else
					{
						if (this.latestMovieHasExtremeSpeed)
						{
							core.player.setStreamQuality(Pyro.CONNECTION_SPEED_HIGH);
							currentSpeedURLs = latestPackage['extreme'];
						}
						else
						{
							// fallback to something here. 
						}
					}
				}
				break;
				
				case Pyro.CONNECTION_SPEED_MEDIUM:
				default:
				if (this.latestMovieHasNormalSpeed)
				{
					currentSpeedURLs = latestPackage['normal'];
				}
				else
				{
					if (this.latestMovieHasExtremeSpeed)
					{
						core.player.setStreamQuality(Pyro.CONNECTION_SPEED_HIGH);
						currentSpeedURLs = latestPackage['extreme'];
					}
					else
					{
						if (this.latestMovieHasLowSpeed)
						{
							core.player.setStreamQuality(Pyro.CONNECTION_SPEED_LOW);
							currentSpeedURLs = latestPackage['low'];
						}
						else
						{
							// fallback to something here. 
						}
					}
				}
				
				break;
				
				case Pyro.CONNECTION_SPEED_HIGH:
				if (this.latestMovieHasExtremeSpeed)
				{
					currentSpeedURLs = latestPackage['extreme'];
				}
				else
				{
					if (this.latestMovieHasNormalSpeed)
					{
						core.player.setStreamQuality(Pyro.CONNECTION_SPEED_MEDIUM);
						currentSpeedURLs = latestPackage['normal'];
					}
					else
					{
						if (this.latestMovieHasLowSpeed)
						{
							core.player.setStreamQuality(Pyro.CONNECTION_SPEED_LOW);
							currentSpeedURLs = latestPackage['low'];
						}
						else
						{
							// fallback to something here. 
						}
					}
				}
				
				break;
			}
			
			this.latestMovieHasDV = currentSpeedURLs['has_dv'] == true ? true : false;
			this.latestMovieHasCC = currentSpeedURLs['has_cc'] == true ? true : false;
			this.latestMovieHasCCDV = currentSpeedURLs['has_cc_dv'] == true ? true : false;
			
			switch(core.player.fileType)
			{
				case NFBPyroBrew.FILE_TYPE_NORMAL:
				this.latestFileURL = parseMovieLink(currentSpeedURLs['url']);
				break;
				
				case NFBPyroBrew.FILE_TYPE_CC:
				this.latestFileURL = parseMovieLink(currentSpeedURLs['cc_url']);
				break;
				
				case NFBPyroBrew.FILE_TYPE_CCDV:
				this.latestFileURL = parseMovieLink(currentSpeedURLs['cc_dv_url']);
				break;
				
				case NFBPyroBrew.FILE_TYPE_DV:
				this.latestFileURL = parseMovieLink(currentSpeedURLs['dv_url']);
				break;
				
			}

			if (latestFileURL == "")
			{
				
				if (currentSpeedURLs['url'] != null)
				{
					core.player.fileType = NFBPyroBrew.FILE_TYPE_NORMAL;
					this.latestFileURL = parseMovieLink(currentSpeedURLs['url']);
					
				}
				else if (currentSpeedURLs['cc_url'] != null)
				{
					core.player.fileType = NFBPyroBrew.FILE_TYPE_CC;
					this.latestFileURL = parseMovieLink(currentSpeedURLs['cc_url']);		
				}	
				else if (currentSpeedURLs['dv_url'] != null)
				{
					core.player.fileType = NFBPyroBrew.FILE_TYPE_DV;
					this.latestFileURL = parseMovieLink(currentSpeedURLs['dv_url']);
				}
				else if (currentSpeedURLs['cc_dv_url'] != null)	
				{
					core.player.fileType = NFBPyroBrew.FILE_TYPE_CCDV;
					this.latestFileURL = parseMovieLink(currentSpeedURLs['cc_dv_url']);
				}
				else
				{
					core.setCurrentState(NFBPlayer.FILE_NOT_FOUND_STATE);
				}
			}	
		}
		
		/**
		 * 
		 * @param url
		 * @return 
		 * 
		 */			
		public function parseMovieLink(url:String):String
		{
			var tempPattern:RegExp = /&id=mp4:/
			var fileURL:String = url.replace(tempPattern, "/");
			
			if (url.indexOf("?") > 0)
			{
				// core.player.streamType = Pyro.STREAM_TYPE_PROXIED_PROGRESSIVE;
			}
			else
			{
				
				if (url.indexOf("mp4") > 0 && core.player.streamNameHasExtension)
				{
					if (fileURL.substring(fileURL.length-4) != ".mp4")
					{
						fileURL += ".mp4";	
					}
				}
			}
			return fileURL; // ({fileURL:fileURL, fileID:fileID});
		}
		
		
		
		/**
		 * 
		 * @param connSpeed
		 * @return 
		 * 
		 */		
		private function parseStreamQuality(streamQual:String):String
		{
			switch (streamQual)
			{
				case Pyro.CONNECTION_SPEED_LOW:
				case "LOW":
				return "low";
				break;
				
				case Pyro.CONNECTION_SPEED_MEDIUM:
				default:
				return "default";
				break;
				
				case Pyro.CONNECTION_SPEED_HIGH:
				case "HIGH":
				return "high";
				break;			
			}
		}	
	}
}